
/*******************************************************************************
 * Copyright (c) 2007 Jules White. All rights reserved.
 * This program and the accompanying materials are made available under the
 * terms of the Common Public License v1.0 which accompanies this distribution,
 * and is available at http://www.eclipse.org/legal/cpl-v10.html
 * 
 * Contributors: Jules White - initial API and implementation
 ******************************************************************************/
package org.refresh.prolog;

import java.util.ArrayList;
import java.util.Collection;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

import org.refresh.core.intelligence.ObjectType;
import org.refresh.core.intelligence.RefreshKB;

public class BasicFactProducer implements FactProducer{
	
	
	private class ListValueConverter implements ValueConverter{
		public String getValue(Object v) {
			
			if(v instanceof Collection){
				Collection c = (Collection)v;
				String val = "[";
				boolean first = true;
				for(Object o : c){
					if(first)
						first = false;
					else
						val += ",";
					
					val += convertValue(o);
				}
				val += "]";
				return val;
			}
			return null;
		}	
	}
	
	
	
	private class NumericValueConverter implements ValueConverter{
		public String getValue(Object v) {
			if(v instanceof Number)
				return ""+v;
			else
				return null;
		}	
	}
	
	private class ToStringValueConverter implements ValueConverter{
		public String getValue(Object v) {
			String val = ""+v;
			val = val.replaceAll("\\\'", "\\apos;");
			val = val.replaceAll("\\\"", "\\quot;");
			val = val.replaceAll("\\n", "\\n;");
			val = val.toLowerCase();
			return val;
		}	
	}
	
	private ObjectManager objectManager_;
	
	private List<ValueConverter> valueConverters_ = new ArrayList<ValueConverter>(4);
	
	public BasicFactProducer(ObjectManager mgr){
		addDefaultValueConverters();
		objectManager_=mgr;
	}
	
	protected void addDefaultValueConverters(){
		getValueConverters().add(new ListValueConverter());
		getValueConverters().add(new NumericValueConverter());
		getValueConverters().add(new ToStringValueConverter());
	}
	
	public List<Fact> produceFacts(Object obj, Map props, List<ObjectType> types, List kb) {
		String id = objectManager_.addObject(obj);
		LinkedList<Fact> facts = new LinkedList<Fact>();
		for(ObjectType t : types){
			InstanceOfFact ifact = new InstanceOfFact(id,t.getName().toLowerCase());
			facts.add(ifact);
		}		
		
		for(Object o : props.keySet()){
			
			String propertyname = ""+o;
			Object value = props.get(o);
			
			String sval = null;
			if(kb.contains(value)){
				sval = objectManager_.getId(value);
			}
			else{
				sval = convertValue(value);
			}
			PropertyFact pf = new PropertyFact(propertyname,id,sval);
			facts.add(pf);
		}
		return facts;
	}
	


	public String convertValue(Object value){
		String sval = null;
		for(ValueConverter vc : valueConverters_){
			sval = vc.getValue(value);
			if(sval != null)
				break;
		}
		return sval;
	}


	public List<ValueConverter> getValueConverters() {
		return valueConverters_;
	}

	public void setValueConverters(List<ValueConverter> valueConverters) {
		valueConverters_ = valueConverters;
	}
	
	
}
